package com.itita.ww2.game.user.event;

import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.itita.ww2.core.MessageHandler;
import com.itita.ww2.data.AllianceConfig;
import com.itita.ww2.data.AllianceConfig.AlRoleType;
import com.itita.ww2.enums.PushCode;
import com.itita.ww2.game.alliance.AllianceManager;
import com.itita.ww2.game.alliance.AllianceService;
import com.itita.ww2.game.alliance.event.AllianceEventDispatch;
import com.itita.ww2.game.alliance.event.IAllianceMemberJoinListener;
import com.itita.ww2.game.alliance.event.IAllianceMemberRemovedListener;
import com.itita.ww2.game.alliance.event.IAllianceMemberRoleChangedListener;
import com.itita.ww2.game.alliance.event.IAllianceMemberRoleChangedListener.ChangedType;
import com.itita.ww2.game.alliance.event.IAllianceRejectJoinListener;
import com.itita.ww2.game.alliance.event.IAllianceTranferListener;
import com.itita.ww2.game.enums.ContributeType;
import com.itita.ww2.game.enums.StateEnum;
import com.itita.ww2.game.user.UserService;
import com.itita.ww2.game.worldmap.WorldMapService;
import com.itita.ww2.game.worldmap.event.IWMAllBaseUpdateListener;
import com.itita.ww2.game.worldmap.event.IWMAllCityUpdateListener;
import com.itita.ww2.game.worldmap.event.IWMBaseDataUpdateListener;
import com.itita.ww2.game.worldmap.event.IWMCityDataUpdateListener;
import com.itita.ww2.game.worldmap.event.IWMCityOccupiedListener;
import com.itita.ww2.game.worldmap.event.WorldMapEventDispatch;
import com.itita.ww2.model.area.AreaCity;
import com.itita.ww2.model.area.AreaCityBattle;
import com.itita.ww2.model.area.AreaWorldMap;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.model.worldmap.Base;
import com.itita.ww2.model.worldmap.City;
import com.itita.ww2.puredb.model.Alliance;
import com.itita.ww2.puredb.model.AllianceMember;
import com.itita.ww2.puredb.model.AllianceUserQuitCD;
import com.itita.ww2.puredb.model.UserAllianceLog;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;

public class UserEventHandler {
	private UserEventHandler() {
	}

	private static final String PUSH_USER_AL = "al"; // user-alliance
	private static final String PUSH_USER_WM = "wm";
	private static UserService userService;

	public static void registerUserEvents(UserService service) {
		userService = service;
		initAlEvent();
		initWMEvent();
	}

	private static void initAlEvent() {
		// 职位变更
		AllianceEventDispatch.addListener(new IAllianceMemberRoleChangedListener() {
			@Override
			public void onAllianceMemberRoleChanged(UserProfile source, UserProfile target,
					AllianceMember allianceMember, ChangedType changedType) {
				ISFSObject pushEvtObj = SFSObject.newInstance();
				ISFSObject pushNoticeObj = SFSObject.newInstance();

				pushEvtObj.putInt("targetRole", allianceMember.getRole());

				pushNoticeObj.putInt("targetRole", allianceMember.getRole());
				pushNoticeObj.putInt("type", changedType.ordinal());

				switch (changedType) {
				case APPOINT:
				case RECALL:
					pushNoticeObj.putUtfString("sourceName", source.getNickname());
					break;
				default:
					break;
				}
				MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_ROLE_CHANGED, pushEvtObj,
						target.getSFSUser());
				MessageHandler.getInstance().pushUserNotice(PUSH_USER_AL, PushCode.ALLIANCE_ROLE_CHANGED, pushNoticeObj,
						target.getSFSUser());
			}
		});
		// 转让
		AllianceEventDispatch.addListener(new IAllianceTranferListener() {

			@Override
			public void onAllianceTransfer(UserProfile source, UserProfile target, AllianceMember sourceMember,
					AllianceMember targetMember, Alliance alliance, StateEnum state) {
				ISFSObject pushObj = SFSObject.newInstance();
				pushObj.putInt("state", state.ordinal());
				switch (state) {
				case REQUEST:// target -> mTransfer
				case CANCEL: // target -> mTransfer
					{
						// TODO 
						pushObj.putBool("mTransfer", targetMember.isTransfer());
						MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_TRANSFER, pushObj,
								target.getSFSUser());
					}
					break;
				case SUCCESS: // source -> role / target -> role mTransfer
					{
						pushObj.putInt("role", sourceMember.getRole());
						pushObj.putBool("mTransfer", sourceMember.isTransfer());

						MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_TRANSFER, pushObj,
								source.getSFSUser());

						pushObj.putInt("role", targetMember.getRole());
						pushObj.putBool("mTransfer", targetMember.isTransfer());
						MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_TRANSFER, pushObj,
								target.getSFSUser());
					}
					break;
				default:
					// DO NOTHING...
					break;
				}
			}
		});
		// 玩家加入联盟
		AllianceEventDispatch.addListener(new IAllianceMemberJoinListener() {
			@Override
			public void onAllianceMemberJoin(UserProfile source, UserProfile target, Alliance alliance,
					AllianceMember allianceMember, JoinType joinType) {
				if (joinType == JoinType.ACCEPT_REQUEST) {

					ISFSObject ret = SFSObject.newInstance();
					ret.putSFSObject("data", AllianceService.getAllianceData(target, alliance));
					MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_JOIN, ret,
							target.getSFSUser());
					ret.removeElement("data");

					if (source == null) {
						return;
					}
					ret.putUtfString("sourceName", source.getNickname());
					MessageHandler.getInstance().pushUserNotice(PUSH_USER_AL, PushCode.ALLIANCE_JOIN, ret,
							target.getSFSUser());
				}
			}
		});
		// 玩家出联盟
		AllianceEventDispatch.addListener(new IAllianceMemberRemovedListener() {

			@Override
			public void onAllianceMemberRemoved(UserProfile source, UserProfile target, Alliance alliance,
					AllianceMember allianceMember, AllianceUserQuitCD allianceUserQuitCD, boolean isKicked) {
				// 被 T 推送
				if (isKicked) {
					MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_KICK, null,
							target.getSFSUser());

					ISFSObject ret = SFSObject.newInstance();
					ret.putUtfString("sourceName", source.getNickname());
					ret.putUtfString("allianceName", alliance.getName());
					MessageHandler.getInstance().pushUserNotice(PUSH_USER_AL, PushCode.ALLIANCE_KICK, ret,
							target.getSFSUser());
				}
			}
		});
		// 玩家被拒绝加入联盟
		AllianceEventDispatch.addListener(new IAllianceRejectJoinListener() {
			@Override
			public void onRejectJoin(UserProfile source, UserProfile target, Alliance alliance,
					AllianceMember allianceMember) {
				ISFSObject ret = SFSObject.newInstance();
				ret.putUtfString("aName", alliance.getName());
				ret.putUtfString("uName", source.getNickname());
				ret.putInt("role", allianceMember.getRole());
				MessageHandler.getInstance().pushUserNotice(PUSH_USER_AL, PushCode.ALLIANCE_REJECT_JOIN, ret,
						target.getSFSUser());
			}
		});
		// 玩家占领据点失败
		UserEventDispatch.addListener(new IUserDefeatedBaseListener() {
			@Override
			public void onUserDefeatedBase(UserProfile atkProfile, UserProfile originProfile, Base base) {
				if (originProfile != null) {
					originProfile.getWMManager().addBaseDefTimes();
				}
			}
		});
		// 玩家占领据点成功
		UserEventDispatch.addListener(new IUserOccupiedBaseListener() {
			@Override
			public void onUserOccupiedBase(UserProfile profile, UserProfile preProfile, String preCityOwnerAid,
					Base base) {
				// 本人占领
				if (profile != null) {
					profile.getWMManager().addBaseOccTimes();
					profile.getWMManager().baseCountOper(1);
				}
				// 本人占领的据点被抢
				if (preProfile != null) {
					preProfile.getWMManager().baseCountOper(-1);
				}
			}
		});
		// 玩家-联盟 捐献修改
		UserEventDispatch.addListener(new IUserAllianceContributeChangedListener() {
			@Override
			public void onUserContributeAllianceChanged(UserProfile userProfile, UserAllianceLog userAlContributionLog,
					AllianceMember allianceMember, int changedAmount, ContributeType type) {
				// 根据历史贡献计算是否提升职位(只有从SOLDIER转变为SERGEANCY)
				AlRoleType roleType = AlRoleType.valueOf(allianceMember.getRole());
				if (roleType == AlRoleType.SOLDIER) {
					if (userAlContributionLog.getTotalContribution() >= AllianceConfig
							.getMinCTB(AlRoleType.SERGEANCY)) {
						allianceMember.setRole(AllianceConfig.getRole(AlRoleType.SERGEANCY));
						AllianceEventDispatch.onAllianceMemberRoleChanged(userProfile, userProfile, allianceMember,
								ChangedType.CONTRIBUTION);
					}
				}
				// 推贡献值刷新客户端数据
				ISFSObject pushObj = SFSObject.newInstance();
				pushObj.putInt("curBaseCTB", allianceMember.getBaseContribution());
				pushObj.putInt("curPayCTB", allianceMember.getPayContribution());
				pushObj.putInt("hisBaseCTB", userAlContributionLog.getBaseContribution());
				pushObj.putInt("hisPayCTB", userAlContributionLog.getPayContribution());
				MessageHandler.getInstance().pushUserEvent(PUSH_USER_AL, PushCode.ALLIANCE_CONTRIBUTION_CHANGED,
						pushObj, userProfile.getSFSUser());
			}
		});
	}

	private static void initWMEvent() {
		// 据点数据更新
		WorldMapEventDispatch.addListener(new IWMBaseDataUpdateListener() {

			@Override
			public void onBaseSimpleDataUpdate(Base base) {
				ISFSObject pushObj = SFSObject.newInstance();
				pushObj.putSFSObject("data", WorldMapService.getBaseSimpleData(base));
				MessageHandler.getInstance().pushWM(PushCode.WORLDMAP_BASE_DATA_UPDATE, pushObj,
						userService.getAreaUsers(new AreaCity(base.getBlockId(), base.getCityId())));
			}
		});
		// 城池数据更新
		WorldMapEventDispatch.addListener(new IWMCityDataUpdateListener() {
			@Override
			public void onCityDataUpdate(City city) {
				List<UserProfile> userProfiles = userService.getAreaUsersProfile(new AreaWorldMap());
				int size = userProfiles.size();
				for (int i = 0; i < size; ++i) {
					UserProfile userProfile = userProfiles.get(i);
					ISFSObject pushObj = SFSObject.newInstance();
					pushObj.putSFSObject("data", WorldMapService.getCityData(userProfile, null, city));
					MessageHandler.getInstance().pushWM(PushCode.WORLDMAP_CITY_DATA_UPDATE, pushObj,
							userProfile.getSFSUser());
				}
			}
		});
		// 所有据点数据更新
		WorldMapEventDispatch.addListener(new IWMAllBaseUpdateListener() {
			@Override
			public void onAllBaseUpdate(City city) {
				ISFSObject pushObj = SFSObject.newInstance();
				pushObj.putSFSArray("data", WorldMapService.getCityBaseList(city.getBlockId(), city.getId()));
				MessageHandler.getInstance().pushWM(PushCode.WORLDMAP_ALLBASE_REFRESH, pushObj,
						userService.getAreaUsers(new AreaCity(city.getBlockId(), city.getId())));
			}
		});
		// 所有城池数据更新
		WorldMapEventDispatch.addListener(new IWMAllCityUpdateListener() {
			@Override
			public void onAllCityUpdate() {
				List<UserProfile> userProfiles = userService.getAreaUsersProfile(new AreaWorldMap());
				int size = userProfiles.size();
				for (int i = 0; i < size; ++i) {
					UserProfile userProfile = userProfiles.get(i);
					ISFSObject pushObj = SFSObject.newInstance();
					pushObj.putSFSArray("data", WorldMapService.getWorldMapData(userProfile));
					MessageHandler.getInstance().pushWM(PushCode.WORLDMAP_ALLCITY_REFRESH, pushObj,
							userProfile.getSFSUser());
				}
			}
		});
		// 城池被占领
		WorldMapEventDispatch.addListener(new IWMCityOccupiedListener() {
			@Override
			public void onAllianceOccupiedCity(City city, UserProfile profile, String preOwnerAid) {
				// 通知玩家  从战斗剔除
				List<UserProfile> userProfiles = userService
						.getAreaUsersProfile(new AreaCityBattle(city.getBlockId(), city.getId()));
				for (UserProfile p : userProfiles) {
					// 忽略攻击者
					if (profile.equals(p)) {
						continue;
					}
					p.getBattleManager().endBattle(false, false);
					MessageHandler.getInstance().pushUserEvent(PUSH_USER_WM, PushCode.WORLDMAP_KICK_BATTLE, null,
							p.getSFSUser());
				}

				// 城池被占领,全服玩家通告
				if (StringUtils.isBlank(preOwnerAid)) {
					// XX(玩家名)带领XX(联盟名)占领了城池XXX
					ISFSObject pushObj = SFSObject.newInstance();
					pushObj.putInt("type", 1);
					pushObj.putUtfString("uName", profile.getNickname());
					Alliance alliance = AllianceManager.getInstance().getAlliance(profile.getAid());
					String aName = "";
					if (alliance != null) {
						aName = alliance.getName();
					}
					pushObj.putUtfString("aName", aName);
					//
					pushObj.putInt("blockId", city.getBlockId());
					pushObj.putInt("cityId", city.getId());
					MessageHandler.getInstance().pushWMNotice(PushCode.WORLDMAP_CITY_OCCUPY_SUCCESS, pushObj,
							userService.getAllUser());
				} else {
					// XX(玩家名)带领XX(联盟名)占领了 XX盟 的 城池XXX
					ISFSObject pushObj = SFSObject.newInstance();
					pushObj.putInt("type", 2);
					pushObj.putUtfString("uName", profile.getNickname());
					Alliance allianceA = AllianceManager.getInstance().getAlliance(profile.getAid());
					String aNameA = "";
					if (allianceA != null) {
						aNameA = allianceA.getName();
					}
					pushObj.putUtfString("aNameA", aNameA);
					Alliance allianceB = AllianceManager.getInstance().getAlliance(preOwnerAid);
					String aNameB = "";
					if (allianceB != null) {
						aNameB = allianceB.getName();
					}
					pushObj.putUtfString("aNameB", aNameB);
					//
					pushObj.putInt("blockId", city.getBlockId());
					pushObj.putInt("cityId", city.getId());
					MessageHandler.getInstance().pushWMNotice(PushCode.WORLDMAP_CITY_OCCUPY_SUCCESS, pushObj,
							userService.getAllUser());
				}
			}
		});
	}
}
